cmake_minimum_required(VERSION 3.31)
set(CMAKE_C_COMPILER clang CACHE STRING "HOST CC")
set(CMAKE_CXX_COMPILER clang++ CACHE STRING "HOST CXX")
set(Git_VERSION 114514 CACHE INTERNAL "" FORCE)
project(mpv-cross C CXX)
set(PROJECT_BINARY_DIR "${${CMAKE_PROJECT_NAME}_BINARY_DIR}")
set(PROJECT_SOURCE_DIR "${${CMAKE_PROJECT_NAME}_SOURCE_DIR}")
include(ProcessorCount)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/download_externalproject.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/custom_steps.cmake)

cmake_policy(SET CMP0097 NEW)
cmake_policy(SET CMP0114 NEW)
if(POLICY CMP0135)
  cmake_policy(SET CMP0135 NEW)
endif()

if(NOT CMAKE_GENERATOR STREQUAL "Ninja")
    message(FATAL_ERROR "Generator “${CMAKE_GENERATOR}” is unsupported!\nTry Ninja if you encounter problems.")
endif()
# Supported arch: x86_64-w64-mingw32 , i686-w64-mingw32 , aarch64-w64-mingw32
set(TARGET_ARCH "x86_64-w64-mingw32" CACHE STRING "The target architecture for this toolchain.")
string(REGEX MATCH "^[^-]+" TARGET_CPU ${TARGET_ARCH})

execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpmachine OUTPUT_VARIABLE HOST_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "^[^-]+" HOST_CPU ${HOST_ARCH})

if(TARGET_CPU STREQUAL "x86_64")
    set(TARGET_CPU_FAMILY "x86_64")
    set(MARCH "x86-64-v3" CACHE STRING "-march for x86_64")
    set(MTUNE ${MARCH} CACHE STRING "-mtune for x86_64")
    if(MARCH MATCHES "x86-64")
        if(MTUNE STREQUAL ${MARCH})
            set(MTUNE "generic")
        endif()
        string(REGEX MATCH "-v[2-4]" MARCH_NAME_DEFAULT ${MARCH})
    else()
        set(MARCH_NAME_DEFAULT "-${MARCH}")
    endif()
elseif(TARGET_CPU STREQUAL "aarch64")
    set(TARGET_CPU_FAMILY "aarch64")
    set(MARCH "cortex-a76" CACHE STRING "-mcpu for aarch64")
    set(MTUNE ${MARCH} CACHE STRING "-mtune for aarch64")
    set(MARCH_NAME_DEFAULT "")
endif()
set(MARCH_NAME ${MARCH_NAME_DEFAULT} CACHE STRING "-march name suffix")

processorcount(CPU_COUNT)
if(CPU_COUNT EQUAL 0)
    set(CPU_COUNT 1)
endif()

if(EXISTS /usr/lib/libmimalloc.so)
    set(MALLOC "/usr/lib/libmimalloc.so" CACHE STRING "set malloc implementation")
elseif(EXISTS /usr/lib/libjemalloc.so)
    set(MALLOC "/usr/lib/libjemalloc.so" CACHE STRING "set malloc implementation")
endif()
if(NOT EXISTS ${MALLOC})
    unset(MALLOC CACHE)
endif()

set(MAKEJOBS ${CPU_COUNT})
# set(MAKEJOBS 5) # uncomment this line to manually change no. of cpu
set(MAKEJOBS ${MAKEJOBS} CACHE STRING "Number of parallel processes to run for each package build")

if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    set (CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/install" CACHE PATH "Default install path" FORCE )
endif()
set(MINGW_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/${TARGET_ARCH} CACHE PATH "Target toolchain path")
set(SINGLE_SOURCE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/src_packages" CACHE PATH "Repository or tarball stored path")
cmake_path(GET CMAKE_INSTALL_PREFIX FILENAME CMAKE_INSTALL_PREFIX_NAME)
cmake_path(GET MINGW_INSTALL_PREFIX FILENAME MINGW_INSTALL_PREFIX_NAME)
option(ENABLE_LEGACY_MPV "Build legacy mpv.exe without consoleAllocationPolicy" OFF)
set(LLVM_ENABLE_LTO "OFF" CACHE STRING "OFF, ON, Thin and Full")
set(LLVM_ENABLE_PGO "OFF" CACHE STRING "OFF, GEN, CSGEN, USE")
if(LLVM_ENABLE_PGO STREQUAL "GEN" OR LLVM_ENABLE_PGO STREQUAL "CSGEN")
    set(LLVM_PROFILE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/profiles/" CACHE PATH "Default profile generation directory")
endif()
if(LLVM_ENABLE_PGO STREQUAL "USE" OR LLVM_ENABLE_PGO STREQUAL "CSGEN")
    set(LLVM_PROFDATA_FILE "" CACHE FILEPATH "Profdata file path")
    if(NOT (EXISTS ${LLVM_PROFDATA_FILE}))
        set(LLVM_ENABLE_PGO OFF)
    endif()
endif()
set(CLANG_PACKAGES_PGO "OFF" CACHE STRING "OFF, GEN, USE")
if(CLANG_PACKAGES_PGO STREQUAL "GEN")
    set(CLANG_PACKAGES_PROFILE_DATA_DIR "profiles/" CACHE STRING "")
elseif(CLANG_PACKAGES_PGO STREQUAL "USE")
    set(CLANG_PACKAGES_PROFDATA_FILE "" CACHE FILEPATH "")
    if(NOT (EXISTS ${CLANG_PACKAGES_PROFDATA_FILE}))
        set(CLANG_PACKAGES_PGO OFF)
    endif()
endif()
option(ENABLE_CCACHE "Enable ccache" OFF)
if(ENABLE_CCACHE)
    set(CCACHE_MAXSIZE "1G" CACHE STRING "Size of ccache")
    set(CCACHE_DIR "${MINGW_INSTALL_PREFIX}/ccache" CACHE STRING "Directory to keep ccached data")
    find_program(CCACHE_EXISTS ccache NO_CACHE)
    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ccache_conf.in ${MINGW_INSTALL_PREFIX}/ccache/ccache.conf @ONLY)
    if(NOT CCACHE_EXISTS)
        set(ENABLE_CCACHE OFF)
    endif()
    option(QT_DISABLE_CCACHE "Disable ccache for qt" OFF)
endif()
set(clang_version 22)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/toolchain.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/toolchain.cmake @ONLY)
set(TOOLCHAIN_FILE ${CMAKE_CURRENT_BINARY_DIR}/toolchain.cmake)
set(CLANG_FLAGS "" CACHE STRING "These flags will be added to the end of the clang args")
set(LLD_FLAGS "" CACHE STRING "These flags will be added to the end of the lld args")
set(TOOLCHAIN_FLAGS "" CACHE STRING "")
set(COMPILER_TOOLCHAIN "clang" CACHE STRING "clang")

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meson_cross.txt.in ${CMAKE_CURRENT_BINARY_DIR}/meson_cross.txt @ONLY)
set(MESON_CROSS ${CMAKE_CURRENT_BINARY_DIR}/meson_cross.txt)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meson_native.txt.in ${CMAKE_CURRENT_BINARY_DIR}/meson_native.txt @ONLY)
set(MESON_NATIVE ${CMAKE_CURRENT_BINARY_DIR}/meson_native.txt)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/exec.in ${CMAKE_CURRENT_BINARY_DIR}/exec @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/exec_host.in ${CMAKE_CURRENT_BINARY_DIR}/exec_host @ONLY)
set(EXEC ${CMAKE_CURRENT_BINARY_DIR}/exec)
set(EXEC_HOST ${CMAKE_CURRENT_BINARY_DIR}/exec_host)
set(MAKE ${EXEC} make -j${MAKEJOBS})

if(TARGET_CPU STREQUAL "x86_64")
    execute_process(
        COMMAND ${EXEC} echo | ${CMAKE_C_COMPILER} --target=x86_64 -dM -E - -march=${MARCH}
        OUTPUT_VARIABLE CC_OUTPUT
    )
    if(CC_OUTPUT MATCHES "__AVX__ 1")
        set(MARCH_HAS_AVX ON)
        if(CC_OUTPUT MATCHES "__AVX512F__ 1")
            set(MARCH_HAS_AVX512 ON)
        endif()
    endif()
endif()

string(TIMESTAMP BUILDDATE "%Y%m%d" UTC)

if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/publish.in)
    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/publish.in ${CMAKE_CURRENT_BINARY_DIR}/publish)
endif()

message(STATUS "MINGW_INSTALL_PREFIX dir: ${MINGW_INSTALL_PREFIX}")
message(STATUS "SINGLE_SOURCE_LOCATION dir: ${SINGLE_SOURCE_LOCATION}")
message(STATUS "Compiler used: ${COMPILER_TOOLCHAIN}")
message(STATUS "Malloc: ${MALLOC}")
message(STATUS "Ccache: ${ENABLE_CCACHE}")
message(STATUS "Target toolchain to build: ${TARGET_ARCH}")

add_subdirectory(toolchain EXCLUDE_FROM_ALL)
add_subdirectory(packages EXCLUDE_FROM_ALL)
